package com.hnblc.blcwms.client.service;

import com.hnblc.blcwms.common.constant.StringPool;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

@Component
public class HttpClientService {


    Logger logger = LoggerFactory.getLogger(HttpClientService.class);
    @Autowired
    CloseableHttpClient httpClient;

    @Autowired
    RequestConfig config;


    private static ResponseHandler<String> stringHandler;


    static {
        stringHandler = response -> {
            int status = response.getStatusLine().getStatusCode();
            if (status >= 200 && status < 300) {
                HttpEntity entity = response.getEntity();
                String result =  entity != null ? EntityUtils.toString(entity) : "无返回数据";
                EntityUtils.consume(entity);
                return result;
            } else {
                HttpEntity entity = response.getEntity();
                throw new ClientProtocolException("Unexpected response status: " + status+":"+EntityUtils.toString(entity));
            }
        };
    }

    /**
     * send a HTTP GET request
     * @param url
     * @param param
     * @return
     * @throws IOException
     */
    public String sendHttpGet(String url,Map param) throws IOException {
        StringBuilder sb1=  new StringBuilder("?");
        Set<String> keySet = param.keySet();
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            sb1.append("&");
            sb1.append(key);
            sb1.append("=");
            sb1.append(param.get(key));
        }
        HttpGet httpGet = new HttpGet(url+sb1.toString());
        httpGet.setConfig(config);
        return this.httpClient.execute(httpGet,stringHandler);
    }

    /**
     * POST form submit Key-Value
     * @param url
     * @param param
     * @return
     * @throws IOException
     */
    public String sendHttpPost(String url, Map<String,String> param) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(config);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        Set<String> keySet = param.keySet();
        Iterator<String> it = keySet.iterator();
        StringBuilder sb = new StringBuilder();
        while(it.hasNext()){
            String key = it.next();
            sb.append(key+"="+param.get(key)+"&");
            nvps.add(new BasicNameValuePair(key, param.get(key)));
        }
        //免URLencoding的POST表单提交
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, StringPool.CHARSET_UTF8);
        logger.debug("************************HttpClient POST request form content*************************\n"+sb.substring(0, sb.length()-1));
        entity.setChunked(true);
        httpPost.setEntity(entity);
        return this.httpClient.execute(httpPost,stringHandler);
    }

    /**
     *  http POST data directly
     * @param url
     * @param content
     * @param contentType
     * @return
     * @throws IOException
     */
    public String sendHttpPost(String url, String content,ContentType contentType) throws IOException{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(config);
        //消息体直接传送
        StringEntity entity = new StringEntity((content),contentType);
        entity.setChunked(true);
        logger.debug("*********************HttpClient POST request contentType***********************\n"+contentType);
        logger.debug("************************HttpClient POST request content*************************\n"+content);
        httpPost.setEntity(entity);
        return this.httpClient.execute(httpPost,stringHandler);
    }

}
